package com.chinaums.study.restful.controller;

import com.chinaums.study.restful.entity.FaceCompareLog;
import com.chinaums.study.restful.service.FaceCompareLogService;
import com.chinaums.study.restful.service.FileCacheService;
import com.chinaums.study.restful.service.RestfulService;
import com.chinaums.study.restful.service.SftpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/pic")
public class PicController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final RestfulService restfulService;

    private final SftpService sftpService;

    private final FileCacheService fileCacheService;

    private final FaceCompareLogService faceCompareLogService;

    public PicController(@Autowired RestfulService restfulService,
                         @Autowired SftpService sftpService,
                         @Autowired FileCacheService fileCacheService,
                         @Autowired FaceCompareLogService faceCompareLogService) {
        this.restfulService = restfulService;
        this.sftpService = sftpService;
        this.fileCacheService = fileCacheService;
        this.faceCompareLogService = faceCompareLogService;
    }

    @PostMapping("upload")
    public Map<String, String> upload(@RequestPart("pic") Part pic) throws IOException {
        final Map<String, String> result = new HashMap<>();
        try (final InputStream in = pic.getInputStream()) {
            result.put("md5", fileCacheService.put(in));
        }
        return result;
    }

    @GetMapping("fetch/{md5}")
    public byte[] fetch(@PathVariable final String md5) {
        return fileCacheService.load(md5);
    }

    @PostMapping("pic-compare")
    public DeferredResult<Map<?, ?>> picCompare(@RequestBody Map<String, String> params) throws Exception {
        final byte[] pic1 = fileCacheService.load(params.get("pic1"));
        final byte[] pic2 = fileCacheService.load(params.get("pic2"));
        final String fileName1 = sftpService.upload(pic1);
        final String fileName2 = sftpService.upload(pic2);
        final CompletableFuture<Map<?, ?>> resFuture = restfulService.compare("/home/sftp" + fileName1, "/home/sftp" + fileName2);
        final DeferredResult<Map<?, ?>> result = new DeferredResult<>();
        resFuture.whenComplete((resp, exception) -> {
            try {
                sftpService.delete(fileName1);
            } catch (Exception e) {
                logger.error(e.getLocalizedMessage(), e);
            }
            try {
                sftpService.delete(fileName2);
            } catch (Exception e) {
                logger.error(e.getLocalizedMessage(), e);
            }
            if (exception != null) {
                result.setErrorResult(exception);
            }
            faceCompareLogService.save(resp);
            result.setErrorResult(resp);
        });
        return result;
    }

    @GetMapping("query-log")
    public Iterable<FaceCompareLog> queryLog(final String keyword) {
        return faceCompareLogService.query(keyword);
    }
}
